using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WowDotNetAPI;
using WowDotNetAPI.Extensions;
using WowDotNetAPI.Models;

namespace Explorers.Test
{
    [TestClass]
    public class RealmTestSL : SilverlightTest
    {
        [TestMethod]
        [Asynchronous]
        public void GetAll_US_Realms_Returns_All_Realms()
        {
            bool done = false;

            IEnumerable<Realm> realmList = null;
            var WowExplorer = new WowExplorer(Region.US);

            WowExplorer.GetRealms(Region.US, cb =>
                    {
                        realmList = cb;
                        done = true;
                    });

            EnqueueConditional(() => done);
            EnqueueCallback(() => Assert.IsTrue(realmList.Any()));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void Get_Valid_US_Realm_Returns_Unique_Realm()
        {
            bool done = false;
            var WowExplorer = new WowExplorer(Region.US);

            Realm realm = null;
            WowExplorer.GetRealms(Region.US, realms =>
            {
                realm = realms.GetRealm("skullcrusher");
                done = true;
            });

            EnqueueConditional(() => done);
            EnqueueCallback(() => Assert.IsNotNull(realm));
            EnqueueCallback(() => Assert.IsTrue(realm.Name == "Skullcrusher"));
            EnqueueCallback(() => Assert.IsTrue(realm.Type == RealmType.PVP));
            EnqueueCallback(() => Assert.IsTrue(realm.Slug == "skullcrusher"));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void Get_All_Realms_By_Type_Returns_Pvp_Realms()
        {
            bool done = false;
            var WowExplorer = new WowExplorer(Region.US);

            Realm realm = null;
            bool allCollectedRealmsArePvp = false;
            WowExplorer.GetRealms(Region.US, realms =>
            {
                realm = realms.GetRealm("skullcrusher");
                IEnumerable<Realm> realmList = realms.WithType(RealmType.PVP);
                allCollectedRealmsArePvp = realmList.Any() &&
                                           realmList.All(r => r.Type == RealmType.PVP);
                done = true;
            });

            EnqueueConditional(() => done);
            EnqueueCallback(() => Assert.IsTrue(allCollectedRealmsArePvp));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void Get_All_Realms_By_Status_Returns_Realms_That_Are_Up()
        {
            bool done = false;
            var WowExplorer = new WowExplorer(Region.US);

            Realm realm = null;
            bool allCollectedRealmsAreUp = false;
            WowExplorer.GetRealms(Region.US, realms =>
            {
                realm = realms.GetRealm("skullcrusher");
                IEnumerable<Realm> realmList = realms.ThatAreUp();

                //All servers being down is likely(maintenance) and will cause test to fail
                allCollectedRealmsAreUp = realmList.Any() &&
                                          realmList.All(r => r.Status == true);
               done = true;
             });

            EnqueueConditional(() => done);
            EnqueueCallback(() => Assert.IsTrue(allCollectedRealmsAreUp));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void Get_All_Realms_By_Queue_Returns_Realms_That_Do_Not_Have_Queues()
        {
            bool done = false;
            var WowExplorer = new WowExplorer(Region.US);

            Realm realm = null;
            bool allCollectedRealmsHaveQueues = false;
            WowExplorer.GetRealms(Region.US, realms =>
            {
                realm = realms.GetRealm("skullcrusher");
                IEnumerable<Realm> realmList = realms.WithoutQueues();

                //All servers getting queues is unlikely but possible and will cause test to fail
                allCollectedRealmsHaveQueues = realmList.Any() &&
                                               realmList.All(r => r.Queue == false);
               done = true;
             });

            EnqueueConditional(() => done);
            EnqueueCallback(() => Assert.IsTrue(allCollectedRealmsHaveQueues));
            EnqueueTestComplete();
        }

        [TestMethod]
        [Asynchronous]
        public void Get_All_Realms_By_Population_Returns_Realms_That_Have_Low_Population()
        {
            bool done = false;
            var WowExplorer = new WowExplorer(Region.US);

            Realm realm = null;
            bool allCollectedRealmsHaveLowPopulation = false;
            WowExplorer.GetRealms(Region.US, realms =>
            {
                realm = realms.GetRealm("skullcrusher");
                IEnumerable<Realm> realmList = realms.WithPopulation(RealmPopulation.LOW);
                allCollectedRealmsHaveLowPopulation = realmList.Any() &&
                                                      realmList.All(r => r.Population == RealmPopulation.LOW);
                done = true;
            }); 
            
         
           EnqueueConditional(() => done);
           EnqueueCallback(() => Assert.IsTrue(allCollectedRealmsHaveLowPopulation));
           EnqueueTestComplete();
        }

        //Assert.ThrowException 
        public static void ThrowsException<T>(Action action, string expectedMessage) where T : Exception
        {
            try
            {
                action.Invoke();
                Assert.Fail("Exception of type {0} should be thrown", typeof(T));
            }
            catch (T e)
            {
                Assert.AreEqual(expectedMessage, e.Message);
            }
        }
    }
}